#include <string.h>

#include "psd_optimize.h"

static LIST_HEAD(listhead, psd_optimizer_t) psd_optimizer_list;

static pthread_mutex_t psd_optimizer_list_lock;

int psd_optimizers_init() {
	LIST_INIT(&psd_optimizer_list);

	if (pthread_mutex_init(&psd_optimizer_list_lock, 0) != 0)
		goto error_exit;

	return 0;

error_exit:
	return -1;
}

psdOptimizer *psd_get_optimizer(const char *name) {
	psdOptimizer *curr;

	pthread_mutex_lock(&psd_optimizer_list_lock);
	{
		for(curr = psd_optimizer_list.lh_first; curr != NULL; curr = curr->list.le_next) {
			if (strcasecmp(curr->name, name) == 0)
				return curr;
		}
	}
	pthread_mutex_unlock(&psd_optimizer_list_lock);

	return NULL;
}

int psd_add_optimizer(psdOptimizer *optimizer) {
	psdOptimizer *curr;

	pthread_mutex_lock(&psd_optimizer_list_lock);
	{
		for(curr = psd_optimizer_list.lh_first; curr != NULL; curr = curr->list.le_next) {
			if (!curr->list.le_next || (curr->list.le_next)->priority > optimizer->priority)
				break;
		}

		if (curr == NULL) {
			LIST_INSERT_HEAD(&psd_optimizer_list, optimizer, list);
		} else {
			LIST_INSERT_AFTER(curr, optimizer, list);
		}
	}
	pthread_mutex_unlock(&psd_optimizer_list_lock);

	return 0;
}

int psd_run_optimizers(const psdSess *sess, const char *depot_id, psdSettings *settings) {
	psdOptimizer *curr;
	int retval = 0;

	pthread_mutex_lock(&psd_optimizer_list_lock);
	{
		for(curr = psd_optimizer_list.lh_first; curr != NULL; curr = curr->list.le_next) {
			if (curr->optimize(sess, depot_id, settings) != 0) {
				retval = -1;
				break;
			}
		}

	}
	pthread_mutex_unlock(&psd_optimizer_list_lock);

	return retval;
}
